/**
 * AtolCD/Spatialytics/widgets/FilterTree.js
 *
 * FilterTree Widget
 *
 * Copyright (C) 2010 AtolCD
 * See LICENSE file under this distribution for licensing information
 * 
 * @author Vincent Plantegenet
 * @since 20100330
 **/


dojo.provide("AtolCD.Spatialytics.widgets.FilterTree");

dojo.require("dijit._Widget");
dojo.require("dijit._Templated");

//UI classes
dojo.require("dijit.TitlePane");
dojo.require("dijit.form.SimpleTextarea");
dojo.require("dijit.form.Button");
dojo.require("dijit.Dialog");

//Tree utils
dojo.require("dojo.data.ItemFileReadStore");
dojo.require("dijit.Tree");
dojo.require("dijit.tree.ForestStoreModel");
dojo.require("my_ext.CheckboxTree");

dojo.require("AtolCD.olap4js.MDXQuery");

dojo.declare("AtolCD.Spatialytics.widgets.FilterTree",
		[dijit._Widget, dijit._Templated], {

	title: "Filter Tree",
	filterButtonLabel: "Filter",
	content: "",
	tree: null,
	o_data: [],
	treedata: null,
	
	templatePath: dojo.moduleUrl("AtolCD.Spatialytics.widgets","templates/FilterTree.html"),
	widgetsInTemplate: true,
	
	// --- private attributes:
	cust_olapAjax: null,
	_dimCellSet: null,
	_secondDlg: null,
	_querymaker: null,
	_olapAjax: null,
	_solapContext: null,
	_config: null,
	_cellCount: null,
	_maxCellCount: null,
	_init:0,
	//var for stroing all cellsets resp
	_cellsTab: [],
	
	
	// -- postCreate function
	postCreate: function () {
		this.inherited(arguments);
	},
	
	initialize: function(config) {

		var that = this;

		that._secondDlg = new dijit.Dialog({
						title: "Loading",
						style: "width: 300px",
						draggable: false
					});
				
		that._secondDlg.attr("content", "Building tree");
		that._secondDlg.show();
		
		that._querymaker = new AtolCD.olap4js.MDXQuery(config,this._solapContext);
		that._cellCount=0;
		that._maxCellCount = config.config2.Cubes[this._solapContext.curr_cube].Dimensions.length-1;
		
		//Customquery with all non geometric, non measure dimensions for building the tree
		var customQuery = config.cube.allDim;	
		that.cust_olapAjax = new GeoSOA.olap4js.OlapAjax(
						{
							olapJSONServiceURL: "SpatialyticsServlet",
							mdxQuery: customQuery
						}
				);
		that.onBuild = new GeoSOA.util.Observable(this);
		//TO FIX
		//Waiting dial that.cust_olapAjax.afterResponseObservable
		//dialMan = new AtolCD.Spatialytics.DialogManager({onObs:that.cust_olapAjax.newRequest,offObs:this.onBuild,message:"Building Tree..."});		

		/**
		*We'll need to get each dimension members, fastest way to get them without having a direct connection to database
		*This method gets full names for each member which is a valuable information for further use(MDX regeneration)
		*
		**/
		that.cust_olapAjax.afterResponseObservable.register(that.getOlapAjaxObserver());
		
		for(var i in config.config2.Cubes[this._solapContext.curr_cube].Dimensions){

			if(i==parseInt(config.config2.geom)){continue;}
			
			str_tmp = "SELECT {[Measures].Members} ON COLUMNS, {["+config.config2.Cubes[this._solapContext.curr_cube].Dimensions[i].name+"].Members} ON ROWS FROM ["+config.config2.Cubes[this._solapContext.curr_cube].name+"]";
			
			that.cust_olapAjax.setMdxQuery(str_tmp);
			
			console.log(str_tmp);
			that.cust_olapAjax.submitQuery();
		}
	},	

	// --- private methods

	//Main function in this widget
	_treeGen: function () {

		var that = this;
		var data = [];
		
		//For each dimension 
		var compteur = 0;
		
		for(var i in that._cellsTab){

			var lvl = 0;//current depth
			var lvlArray = [];//number of children to add in this depth
			var posArray = [];
			var lvlPos = [];//Position of the depth in the data set
			var leaf = false;
			
			for(var j in that._cellsTab[i].axes[1].members[0]){

				lvlNum = that._cellsTab[i].axes[1].members[0][j].properties.LEVEL_NUMBER;
				parLvl = that._cellsTab[i].axes[1].members[0][j].properties.PARENT_LEVEL;
				posArray[lvlNum] = 0;
					
				//First of this dimension should be the dimension itself (all items)
				m_type = (j==0)?"Dimension":"Membre";
			
				//if card !=0 this item is not a leaf, next will be deeper
				if(that._cellsTab[i].axes[1].members[0][j].properties.CHILDREN_CARDINALITY!=0){
					
					lvlArray[lvlNum] = that._cellsTab[i].axes[1].members[0][j].properties.CHILDREN_CARDINALITY;
					
					lvlPos[lvlNum] = compteur;
					uid = that._cellsTab[i].axes[1].members[0][j].properties.MEMBER_UNIQUE_NAME;
					did = that._cellsTab[i].axes[1].members[0][j].properties.DIMENSION_UNIQUE_NAME;
					//Add this item to the tree
					data[compteur] = { name: that._cellsTab[i].axes[1].members[0][j].name, id: uid, type: m_type, children:[], dim : did};

					//if lvl > 1 this item has a parent
					if(that._cellsTab[i].axes[1].members[0][j].properties.PARENT_COUNT!=0){
						data[lvlPos[parLvl]].children[posArray[parLvl]] = {_reference: uid};
						lvlArray[parLvl]--;
						posArray[parLvl]++;
					}
				}
				//Card == 0, this item is a leaf
				else{
				
					uid = that._cellsTab[i].axes[1].members[0][j].properties.MEMBER_UNIQUE_NAME;
					did = that._cellsTab[i].axes[1].members[0][j].properties.DIMENSION_UNIQUE_NAME;
					//Leaf level has been found
					leaf = true;
					data[compteur] = { name: that._cellsTab[i].axes[1].members[0][j].name, id: uid, type: m_type, dim : did};

					data[lvlPos[parLvl]].children[posArray[parLvl]] = {_reference: uid};
					lvlArray[parLvl]--;
					posArray[parLvl]++;
				}
				compteur++;
			}
		}

		//First we have to get all dimensions from our cellset.axes
		//then get each members and build the tree with childrens
		
		//Starting tree creation
		that.treeData = {
			label: 'name',
			identifier: 'id',
			items:
			data
		};

		//Store for datas
		var store = new dojo.data.ItemFileWriteStore({
			data: that.treeData
		});

		//Model for building the tree
		model = null;
		model = new dijit.tree.ForestStoreModel({
			store: store,   
			query: {type: 'Dimension'},
			rootId: "root",
			rootLabel: "Dimensions",
			childrenAttrs: ["children"]
			});

		
		
		//We must replace old node by a new one
		that.ftname = "filterTree"+Math.round(Math.random()*11);
		dojo.place("<div id=\""+that.ftname+"\"></div>", "treeMainDiv_pane", "only");

		
		//Model assignation 
		that.tree = new my_ext.CheckboxTree(
		{
			showRoot : false,
			openOnClick : false,
			setCheckboxOnClick : true,
			model: model,
		}, ""+that.ftname);

		dojo.connect(that.tree, 'onClick', function(node) {

		   	if(node.checked=="true"){
				//that._onNodeChecked(node);
				that._querymaker.addVal(node);
			}
			else if(node.checked=="false"){
				//that._onNodeUnChecked(node);
				that._querymaker.remVal(node)
			}
		});
		
		//renders the tree
		that.tree.startup();


		/*
		
		
		//Order tree -- Modified version
		cells = that._cellsTab[0];
		
		this.o_data[0] = { name: "Rows", id: "Rows", type: "base", children:[]};
		this.o_data[1] = { name: "Columns", id: "Columns", type: "base", children:[]};
		this.o_data[2] = { name: "Filter", id: "Filter", type: "base", children:[]};
		
		cpt = 3;
		
		//Adding rows children
		curr_chil = 0;
		for(var k in cells.metadata.axesMeta[0].hierarchies){//Rows
			
			uid = "["+cells.metadata.axesMeta[0].hierarchies[k].dimensionName+"]";
			this.o_data[cpt] = { name: cells.metadata.axesMeta[0].hierarchies[k].dimensionName, id: uid, type: "Value"};
			this.o_data[2].children[curr_chil] = {_reference: uid};
			curr_chil++;
			cpt++;
		}
		//Adding cols children
		curr_chil = 1;
		for(var k in cells.metadata.axesMeta[1].hierarchies){//Columns
			
			uid = "["+cells.metadata.axesMeta[1].hierarchies[k].dimensionName+"]";
			this.o_data[cpt] = { name: cells.metadata.axesMeta[1].hierarchies[k].dimensionName, id: uid, type: "Value"};
			this.o_data[2].children[curr_chil] = {_reference: uid};
			curr_chil++;
			cpt++;
		}
		
		//Adding filter children
		curr_chil = 0;
		for(var k in cells.metadata.filterAxisMeta.hierarchies){//Filter Axis
			
			uid = "["+cells.metadata.filterAxisMeta.hierarchies[k].dimensionName+"]";
			
			if(uid.toString() == this.geodim){
				this.o_data[cpt] = { name: cells.metadata.filterAxisMeta.hierarchies[k].dimensionName, id: uid, type: "Value"};
				this.o_data[0].children[0] = {_reference: uid};
				curr_chil++;
				cpt++;
			}
			else if(uid.toString() == "[Measures]"){
				this.o_data[cpt] = { name: cells.metadata.filterAxisMeta.hierarchies[k].dimensionName, id: uid, type: "Value"};
				this.o_data[1].children[0] = {_reference: uid};
				curr_chil++;
				cpt++;
			}
		}
		
		//Starting tree creation
		var o_treeData = {
			label: 'name',
			identifier: 'id',
			items: this.o_data
		};

		//Store for datas
		var o_store = new dojo.data.ItemFileWriteStore({
			data: o_treeData
		});

		//Model for building the tree
		o_model = new dijit.tree.ForestStoreModel({
			store: o_store,   
			query: {type: 'base'},
			rootId: "root",
			rootLabel: "Dimensions",
			childrenAttrs: ["children"]
			});
		
		var func = function(target, source)
		{
			//convert the target (DOM node) to a tree node and
			//then get the  item out of it
			var item = dijit.getEnclosingWidget(target).item;

			//DO NOT allow DnD over Value node(leaf)
			if(item.type == "Value")
				return false;
			
			//then allow DnD over base items but not root.
			return (item.id != "root" && item.type == "base");
		};
		
		//Model assignation 
		o_tree = new dijit.Tree(
		{
			showRoot : false,
			openOnClick : false,
			setCheckboxOnClick : true,
			model: o_model,
			checkItemAcceptance: func,
			dndController: "dijit.tree.dndSource" 
		}, "orderDiv");

		//Start the order tree
		o_tree.startup();
*/
		
		that._secondDlg.hide();
		
		//we don't need these anymore
		that.cust_olapAjax.afterResponseObservable.unregister(that.getOlapAjaxObserver());
		
		delete that.cust_olapAjax;
		delete cells;
	},

	// --- getters/setters
	
	_setTitleAttr: function (/*String*/ title) {
		this.title = title;
		this.filterTreeWidget.attr('title', this.title);
	},
	
	_setFilterButtonLabelAttr: function (/*String*/ label) {
		this.filterButtonLabel = label;
		this.filterButtonWidget.attr('label', this.filterButtonLabel);
	},

	// --- public methods
	
	getOlapAjaxObserver: function () {
		var that = this;
		var closure = function(olapAjax) {
			//stocker le cellset dans le tableau 
			that._cellsTab[that._cellCount] = olapAjax.getCellSet();

			if(that._cellCount==(that._maxCellCount-1)){
				that._treeGen();
			}
			else{
			console.log(that._cellCount);
				that._cellCount++;
			}
		};
		return closure;
	},

	filter: function () {
		
		this._solapContext.reqDone = true;
		
		feat = this._solapContext.vectorLayer.selectedFeatures;

		query = this._querymaker.getQuery(feat)
		
		this._olapAjax.setMdxQueries(query,this._querymaker.getQueryObj());
		this._olapAjax.submitQuery();
	},
	
	attachSOLAPContext: function (/*GeoSOA.Spatialytics.SOLAPContext*/ solapContext) {
		this._solapContext = solapContext;
	},
	
	detachSOLAPContext: function () {
		if (this._solapContext != null) {
			this._solapContext = null;
		}
	},
	
	attachOlapAjax: function (/*GeoSOA.olap4js.OlapAjax*/ olapAjax) {
		this._olapAjax = olapAjax;
	}
});
